<template>
  <div class="login-wrap">
    <div class="login-content">
      <div class="header-box">
        <header-text :fontSize="61" />
      </div>
      <div class="login-box">
        <div class="model-bg"><img src="../assets/img/model-bg.png" alt=""></div>
        <div class="ms-login">
          <div class="ms-title"><img src="../assets/img/ms-title.png" alt=""></div>
          <template v-if="loginStyle === 1">
            <div v-if="codeLoginShow" class="ms-tab">
              <span :class="['tab-password', { 'active': loginType === 1 }]" @click="switchLoginType(1)">密码登录</span>
              <span :class="['tab-code', { 'active': loginType === 2 }]" @click="switchLoginType(2)">验证码登录</span>
            </div>
          </template>
          <template v-else>
            <div v-if="codeLoginShow" class="ms-tab1">
              <span :class="['tab-code', { 'active': loginType === 2 }]" @click="switchLoginType(2)">验证码登录</span>
              <span :class="['tab-password', { 'active': loginType === 1 }]" @click="switchLoginType(1)">应急登录</span>
            </div>
          </template>
          <el-form
            ref="refLoginForm"
            :model="loginForm"
            :rules="dynamicRules"
            label-width="0px"
            class="login-form"
            :validate-on-rule-change="false"
            :style="{ 'padding-top': codeLoginShow ? '20px' : '50px' }"
          >
            <el-form-item v-if="loginType === 1" key="username" prop="username">
              <div class="bg">
                <el-input
                  size="large"
                  ref="refUsername"
                  v-model.trim="loginForm.username"
                  placeholder="请输入用户编号"
                  @keyup.enter="focusNext('password')"
                />
              </div>
            </el-form-item>
            <el-form-item v-if="loginType === 2" key="telephone" prop="telephone">
              <div class="bg">
                <el-input
                  size="large"
                  v-model.trim="loginForm.telephone"
                  placeholder="请输入手机号码"
                  @keyup.enter="focusNext('verificationCode')"
                />
              </div>
            </el-form-item>
            <el-form-item v-if="loginType === 1" key="password" prop="password">
              <div class="bg">
                <el-input
                  size="large"
                  ref="refPassword"
                  v-model="loginForm.password"
                  type="password"
                  placeholder="请输入密码"
                  @keyup.enter="handleLogin()"
                />
              </div>
            </el-form-item>
            <el-form-item v-if="loginType === 2" key="verificationCode" prop="verificationCode">
              <div class="bg">
                <el-input
                  size="large"
                  ref="refVerificationCode"
                  v-model="loginForm.verificationCode"
                  placeholder="请输入验证码"
                  @keyup.enter="handleLogin()"
                />
                <el-button class="btn-code" link :disabled="!btnStatus" @click="getCode">
                  {{ btnStatus ? '获取验证码' : `获取验证码(${ countDownTime }s)` }}
                </el-button>
              </div>
            </el-form-item>
            <el-form-item prop="agreement">
              <div class="agreement">
                <el-checkbox v-model="agree">同意系统隐私声明并遵守相关法律和规章制度</el-checkbox>
              </div>
            </el-form-item>
            <div :class="agree ? 'login-btn' : 'login-btn-disabled'">
              <el-button size="large" type="primary" :loading="loading" :disabled="!agree" @click="handleLogin">登 录</el-button>
            </div>
          </el-form>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { cloneDeep } from 'lodash'
import md5 from 'js-md5'

export default {
  setup() {
    const route = useRoute()
    const router = useRouter()
    const userStore = useUserStore()
    const refLoginForm = ref()
    const refUsername = ref()
    const refPassword = ref()
    const refVerificationCode = ref()
    const validateUsername = (rule, value, callback) => {
      if (!(value && value.length > 0)) {
        callback(new Error('请输入用户编号'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (!value) {
        callback(new Error('请输入用户密码'))
      } else {
        callback()
      }
    }
    const validateTelephone = (rule, value, callback) => {
      const reg = /^[1]([3-9])[0-9]{9}$/
      if (!(value && value.length > 0)) {
        callback(new Error('请输入手机号'))
      } else if (!reg.test(value)) {
        callback(new Error('请输入正确手机号码'))
      } else {
        callback()
      }
    }
    const validateCode = (rule, value, callback) => {
      if (!value) {
        callback(new Error('请输入验证码'))
      } else {
        callback()
      }
    }
    const state = reactive({
      loginType: 1,
      loginStyle: 1,
      redirect: undefined,
      otherQuery: {},
      loginForm: {
        username: '',
        password: '',
        telephone: '',
        verificationCode: ''
      },
      loginRules: {
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }]
      },
      loginCodeRules: {
        telephone: [{ required: true, trigger: 'blur', validator: validateTelephone }],
        verificationCode: [{ required: true, trigger: 'blur', validator: validateCode }]
      },
      loading: false,
      capsTooltip: false,
      showPsw: false,
      agree: true,
      passwordType: 'password',
      codeLoginShow: true, // 是否显示验证码登录
      btnStatus: true,
      countDownTimer: null,
      countDownTime: 60, // 显示的倒计时时间
      constCount: 60 // 倒计时时间
    })
    const dynamicRules = computed(() => {
      return state.loginType === 1 ? state.loginRules : state.loginCodeRules
    })
    onMounted(async () => {
      state.loginStyle = await getLoginStyle()
      state.loginType = state.loginStyle
      const { query } = route
      if (state.loginForm.username === '') {
        refUsername.value?.focus()
      } else if (state.loginForm.password === '') {
        refPassword.value?.focus()
      }
      if (query) {
        state.redirect = query.redirect
        state.otherQuery = getOtherQuery(query)
      }
    })
    const getOtherQuery = (query) => {
      return Object.keys(query).reduce((acc, cur) => {
        if (cur !== 'redirect') {
          acc[cur] = query[cur]
        }
        return acc
      }, {})
    }
    // 切换登录类型
    const switchLoginType = (val) => {
      state.loginType = val
      refLoginForm.value.resetFields()
    }
    const focusNext = (nextRef) => {
      switch (nextRef) {
        case 'password':
          refPassword.value?.focus()
          break
        case 'verificationCode':
          refVerificationCode.value?.focus()
          break
      }
    }
    const getCode = () => {
      refLoginForm.value?.validateField('telephone', valid => {
        if (valid) {
          request({
            url: '/mobileVerificationCode',
            method: 'get',
            params: { telephone: state.loginForm.telephone }
          }).then(res => {
            const endMsRes = new Date().getTime() + state.constCount * 1000 // 当前时间戳加上this.constCount的时间戳，相当于当前时间this.constCount以后的时间戳
            localStorage.setItem('myEndTime', JSON.stringify(endMsRes)) // 把这个this.constCount时候的事件戳存起来
            codeCountDown(endMsRes)
            if (res.code === 200) {
              ElMessage.success('验证码发送成功。')
            } else {
              ElMessage.error(res.data.error || res.message)
            }
          })
        }
      })
    }
    const codeCountDown = (endMsRes) => {
      state.countDownTime = Math.ceil((endMsRes - new Date().getTime()) / 1000) // 剩余多少秒
      state.btnStatus = state.countDownTime < 0
      if (state.countDownTimer) clearTimeout(state.countDownTimer)
      state.countDownTimer = setTimeout(() => {
        state.countDownTime--
        if (state.countDownTime < 1) {
          state.btnStatus = true
          state.countDownTime = state.constCount
          localStorage.removeItem('myEndTime')
          clearTimeout(state.countDownTimer)
        } else {
          state.btnStatus = false
          codeCountDown(endMsRes)
        }
      }, 1000)
    }
    const handleLogin = () => {
      if (!state.agree) return
      refLoginForm.value?.validate(valid => {
        if (valid) {
          const loginPra = cloneDeep(state.loginForm)
          loginPra.password = md5(loginPra.password) // 密码使用MD5加密
          const url = state.loginType === 1 ? '/login' : '/loginByVerificationCode'
          let params = state.loginType === 1 ? { userid: loginPra.username, password: loginPra.password } : { telephone: loginPra.telephone, verificationCode: loginPra.verificationCode }
          userStore.login(url, params).then(success => {
            state.loading = false
            if (success) {
              localStorage.removeItem('myEndTime')
              if (state.countDownTimer) clearTimeout(state.countDownTimer)
              router.push({ path: state.redirect || '/', query: state.otherQuery })
              // router.push({ path: '/dashboard' })
              // router.go(0)// 登录成功后强制刷新页面
              Cookies.set('lastOperationTime', new Date().getTime()) // 写入最后操作时间cookie
            }
          }).catch(() => {
            state.loading = false
          })
        }
      })
    }
    return {
      refLoginForm,
      refUsername,
      refPassword,
      refVerificationCode,
      dynamicRules,
      switchLoginType,
      focusNext,
      getCode,
      handleLogin,
      ...toRefs(state)
    }
  }
}
</script>

<style lang="scss" scoped>
.login-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: auto;

  .login-content {
    background: url(../assets/img/login-bg.png) no-repeat;
    background-size: cover;
    width: 100%;
    height: 100%;
    min-width: 1900px;
    min-height: 929px;
    overflow: hidden;
    position: relative;

    .header-box {
      width: 100%;
      margin-top: 5%;
      color: #2A9CDD;
    }

    .login-box {
      width: 1240px;
      height: 412px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      display: flex;

      .model-bg {
        position: absolute;
        left: 0;
        top: 0;
        animation: move 1s infinite linear alternate;
      }

      .ms-login {
        position: absolute;
        right: 0;
        top: 20px;
        width: 555px;
        height: 358px;
        background: url(../assets/img/ms-bg.png) no-repeat center top;
        overflow: hidden;

        .ms-title {
          width: 100%;
          height: 55px;
          text-align: center;

          img {
            margin-top: 18px;
          }
        }

        .ms-tab {
          height: 50px;
          text-align: center;
          font-size: 16px;
          color: #0E6AB7;
          padding-top: 28px;
          font-weight: 400;
          letter-spacing: 0.8px;
          box-sizing: border-box;

          .tab-password {
            cursor: pointer;
            margin-right: 35px;
          }

          .tab-code {
            cursor: pointer;
            margin-left: 35px;
          }

          .active {
            font-size: 18px;
            color: #00D2FF;
            letter-spacing: 0.9px;
          }
        }

        .ms-tab1 {
          height: 50px;
          text-align: center;
          font-size: 16px;
          color: #0E6AB7;
          padding-top: 28px;
          font-weight: 400;
          letter-spacing: 0.8px;

          .tab-password {
            cursor: pointer;
            margin-left: 35px;
          }

          .tab-code {
            cursor: pointer;
            margin-right: 35px;
          }

          .active {
            font-size: 18px;
            color: #00D2FF;
            letter-spacing: 0.9px;
          }
        }

        .login-form {
          padding: 10px 120px 0;

          :deep(.el-form-item__error) {
            left: unset;
            right: 32px;
          }

          .bg {
            position: relative;
            width: 100%;
            background: url(../assets/img/input-bg.png) no-repeat center;
            --el-fill-color-blank: transparent;
            --el-border-color: transparent;
            --el-color-danger: transparent;

            :deep(.el-input) {
              .el-input__wrapper {
                --el-input-hover-border-color: transparent;
                --el-input-focus-border-color: transparent;

                .el-input__inner {
                  padding: 0 36px !important;
                  border: none;
                  color: #4595D9;

                  &::-webkit-input-placeholder {
                    /* WebKit browsers 适配谷歌 */
                    color: #1C4787;
                  }

                  &::-moz-placeholder {
                    /* Mozilla Firefox 4 to 18 适配火狐 */
                    color: #1C4787;
                  }
                }
              }
            }

            .btn-code {
              font-weight: 400;
              position: absolute;
              top: 10px;
              right: 35px;
              color: #00D2FF;
            }

            .is-disabled {
              color: #627A97;
            }
          }

          :deep(.el-button--primary) {
            font-size: 16px;
            font-weight: bold;
            color: #EEEEEE;
            background-color: transparent;
            border-color: transparent;
            width: 100%;
            height: 36px;
            margin: 0;
            line-height: 0;

            &.is-loading:before {
              background: transparent;
            }
          }

          .login-btn {
            padding: 0 50px;
            text-align: center;
            background: url(../assets/img/button-bg.png) no-repeat center top;
          }

          .login-btn-disabled {
            padding: 0 50px;
            text-align: center;
            background: url(../assets/img/button-bg-disabled.png) no-repeat center top;
          }

          .agreement {
            padding-left: 20px;

            :deep(.el-checkbox) {
              --el-checkbox-bg-color: transparent;
              --el-checkbox-input-border: 1px solid #276295;
              --el-checkbox-checked-bg-color: transparent;
              --el-checkbox-checked-input-border-color: #276295;
              --el-checkbox-checked-icon-color: #276295;
              --el-checkbox-text-color: #225988;
              --el-checkbox-font-size: 12px;
              --el-checkbox-input-width: 12px;
              --el-checkbox-input-height: 12px;
              --el-checkbox-checked-text-color: #ccc;

              .el-checkbox__inner:after {
                height: 6px;
                left: 3px;
              }
            }
          }
        }
      }
    }
  }
}

/* 上下动画 */
@keyframes move {
  from {
    top: 0px;
  }

  to {
    top: 20px;
  }
}
</style>
